package cn.ant.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/***
 * RabbitMQ配置交换机、队列、以及绑定关系
 * @author Anhui AntLaddie <a href="https://juejin.cn/user/4092805620185316">(掘金蚂蚁小哥)</a>
 * @version 1.0
 **/
@Configuration
public class RabbitMQConfig {

    /* 一些简单的交换机-->路由-->队列的方式配置*/
    // 直接交换机
    public static final String CONFIRM_EXCHANGE = "confirmExchange";
    // 队列
    public static final String CONFIRM_QUEUE = "confirmQueue";
    // 绑定路由key
    public static final String CONFIRM_ROUTING_KEY = "confirmRoutingKey";
    /*针对一些备份交换机的配置*/
    // 备份交换机
    public static final String BACKUP_EXCHANGE = "backupExchange";
    // 备份队列（把一些无法被路由的消息进行备份）
    public static final String BACKUP_QUEUE = "backupQueue";
    // 报警队列（报警队列用来发送报警消息，告知消费者处理，以达到让管理员知道有数据处理不了）
    public static final String WARNING_QUEUE = "warningQueue";

    // ========================== 一些简单的队列和交换机的声明 ==========================

    /***
     * 创建交换机消息
     * @return Exchange
     */
    @Bean("confirmExchange")
    public Exchange createConfirmExchange() {
        // 一些其它参数
        Map<String, Object> arguments = new HashMap<>();
        // 设置备份交换机信息，将来发送的消息无法被路由，就会发送到备份交换机
        arguments.put("alternate-exchange", BACKUP_EXCHANGE);
        // 构建出交换机返回
        return ExchangeBuilder.directExchange(CONFIRM_EXCHANGE).durable(true)
                .withArguments(arguments).build();
    }

    /***
     * 队列名称
     * @return Queue
     */
    @Bean("confirmQueue")
    public Queue createConfirmQueue() {
        return QueueBuilder.durable(CONFIRM_QUEUE).build();
    }

    /***
     * 绑定关系
     * @param confirmExchange 交换机消息
     * @param confirmQueue 队列消息
     * @return Binding
     */
    @Bean("confirmQueueBindConfirmExchange")
    public Binding setConfirmQueueBindConfirmExchange(
            @Qualifier(value = "confirmExchange") Exchange confirmExchange,
            @Qualifier(value = "confirmQueue") Queue confirmQueue) {
        return BindingBuilder.bind(confirmQueue).to(confirmExchange).with(CONFIRM_ROUTING_KEY).noargs();
    }

    // ============================== 备份交换机的创建 ==============================

    /***
     * 创建备份交换机消息
     * @return Exchange
     */
    @Bean("backupExchange")
    public Exchange createBackupExchange() {
        return ExchangeBuilder.fanoutExchange(BACKUP_EXCHANGE).durable(true).build();
    }

    /***
     * 备份队列名称
     * @return Queue
     */
    @Bean("backupQueue")
    public Queue createBackupQueue() {
        return QueueBuilder.durable(BACKUP_QUEUE).build();
    }

    /***
     * 报警队列名称
     * @return Queue
     */
    @Bean("warningQueue")
    public Queue createWarningQueue() {
        return QueueBuilder.durable(WARNING_QUEUE).build();
    }

    /***
     * 绑定关系（备份队列绑定到备份交换机上）
     * @param backupExchange 备份交换机消息
     * @param backupQueue 备份队列消息
     * @return Binding
     */
    @Bean("backupQueueBindBackupExchange")
    public Binding setBackupQueueBindBackupExchange(@Qualifier(value = "backupExchange") Exchange backupExchange,
                                                    @Qualifier(value = "backupQueue") Queue backupQueue) {
        return BindingBuilder.bind(backupQueue).to(backupExchange).with("").noargs();
    }

    /***
     * 绑定关系（报警队列绑定到备份交换机上）
     * @param backupExchange 备份交换机消息
     * @param warningQueue 报警队列消息
     * @return Binding
     */
    @Bean("warningQueueBindBackupExchange")
    public Binding setWarningQueueBindBackupExchange(@Qualifier(value = "backupExchange") Exchange backupExchange,
                                                     @Qualifier(value = "warningQueue") Queue warningQueue) {
        return BindingBuilder.bind(warningQueue).to(backupExchange).with("").noargs();
    }
}
